package me.zhengjie.modules.quartz.task;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qiaofang.applet.constants.MessageTypeEnum;
import com.qiaofang.applet.constants.ReceiverTypeEnum;
import com.qiaofang.applet.constants.RemindModeEnum;
import com.qiaofang.applet.service.member.service.EmployeeReportService;
import com.qiaofang.applet.service.member.service.dto.CreateMessageDTO;
import com.qiaofang.applet.service.member.service.dto.EmployeeDailyDto;
import com.qiaofang.applet.service.member.service.dto.ReceiverDTO;
import com.qiaofang.applet.service.other.domain.CityCompany;
import com.qiaofang.applet.service.other.domain.Corporation;
import com.qiaofang.applet.service.other.service.CorporationService;
import com.qiaofang.common.exception.BusinessException;
import com.qiaofang.common.request.DataRequest;
import com.qiaofang.common.util.StringUtil;
import com.qiaofang.core.gatewayclient.GatewayTemplate;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.quartz.service.dto.SyncCommon;
import me.zhengjie.modules.quartz.task.dto.CreateMessageListRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Author: youqing.yang
 * @Create: 2021/03/29 11:12
 * @Description:
 **/
@Slf4j
@Component
public class EmployeeDailyTask {

    private static final String SENT_MESSAGE_DAILY_TO_ALL_API = "/fyapi/v1/fyapi/miniProgramMessageFacade/sentDailyToAll";

    private static final String V20_SENT_ALL_MESSAGE_API = "/api/jedioperation/op/message/createMessageList";

    public static final String MSG_TRIGGER_SYS = "系统";

    public static final String MESSAGE_SUB_TITLE = "官网小程序";

    @Autowired
    private CorporationService corporationService;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private EmployeeReportService employeeReportService;

    @Autowired
    private GatewayTemplate gatewayTemplate;

    private RestTemplate template;

    {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(300000);
        requestFactory.setReadTimeout(300000);
        template = new RestTemplate(requestFactory);
    }

    public void run() {
        log.info("EmployeeDailyTask run start");
        Corporation corporation = new Corporation();
        corporation.setDeleted(Boolean.FALSE);
        corporation.setV20Flag(Boolean.FALSE);
        Iterable<Corporation> list = corporationService.findAll(Example.of(corporation));
        list.forEach(item -> {
            String corporationCode = item.getCorporationCode();
            if (StringUtil.isEmpty(item.getPullDomain())) {
                log.error("集团:{} 的同步数据域名未配置", corporationCode);
                return;
            }

            //处理v20公司经纪人行为日报
            if (item.getV20Flag()) {
                sentMessageDailyToV20Company(item);
                return;
            }

            Criteria criteria = Criteria.where("corporationCode").is(corporationCode).and("status").is(1);
            List<CityCompany> companies = mongoTemplate.find(new Query(criteria), CityCompany.class);
            companies.forEach(company -> {
                SyncCommon syncCommon = new SyncCommon();
                syncCommon.setCorporationCode(item.getCorporationCode());
                syncCommon.setAppId(item.getPullAppId());
                syncCommon.setAppKey(item.getPullAppKey());
                syncCommon.setDomain(item.getPullDomain());
                syncCommon.setCityCode(company.getCityCode());
                syncCommon.setCompanyUuid(company.getCompanyUuid());

                //这里需要传入该公司经纪人所有的行为数据
                log.info("开始处理公司:{}的经纪人行为日报数据，开始时间:{}", company.getCompanyUuid(), new Date());
                sentMessageDailyToCompany(syncCommon);
                log.info("完成处理公司:{}的经纪人行为日报数据，结束时间:{}", company.getCompanyUuid(), new Date());
            });
        });
        log.info("EmployeeDailyTask run end");
    }

    private void sentMessageDailyToCompany(SyncCommon syncCommon) {
        List<EmployeeDailyDto> employeeDailyDtoList = employeeReportService.listTotalEmployeeDaily(syncCommon.getCompanyUuid());

        List<List<EmployeeDailyDto>> partition = Lists.partition(employeeDailyDtoList, 200);
        for (List<EmployeeDailyDto> employeeDailyDtos : partition) {
            httpRequestData(syncCommon, SENT_MESSAGE_DAILY_TO_ALL_API, employeeDailyDtos);
        }
    }

    public void sentMessageDailyToV20Company(Corporation corporation) {
        Criteria criteria = Criteria.where("corporationCode").is(corporation.getCorporationCode()).and("status").is(1);
        List<CityCompany> companies = mongoTemplate.find(new Query(criteria), CityCompany.class);
        companies.forEach(company -> {

            HttpHeaders headers = new HttpHeaders();
            headers.add("companyUuid", company.getCompanyUuid());

            List<EmployeeDailyDto> employeeDailyDtoList = employeeReportService.listTotalEmployeeDaily(company.getCompanyUuid());
            List<List<EmployeeDailyDto>> partition = Lists.partition(employeeDailyDtoList, 500);

            log.info("开始处理V20公司:{}的经纪人行为日报数据，开始时间:{}", company.getCompanyUuid(), new Date());
            for (List<EmployeeDailyDto> employeeDailyDtos : partition) {
                sentMessageForList(employeeDailyDtos, headers);
            }
           log.info("完成处理V20公司:{}的经纪人行为日报数据，结束时间:{}", company.getCompanyUuid(), new Date());
        });
    }

    private void sentMessageForList(List<EmployeeDailyDto> employeeDailyDtoList, HttpHeaders headers) {
        if (CollectionUtils.isEmpty(employeeDailyDtoList)){
            log.error("接收消息体不存在,发送日报消息失败");
            throw new BusinessException("接收消息体不存在,发送日报消息失败");
        }

        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.DAY_OF_YEAR, instance.get(Calendar.DAY_OF_YEAR) - 1);

        String date = DateUtil.format(instance.getTime(), "MM-dd");
        String PROCESS_CHANGE_MORTGAGE =
                "1. 您分享了房源/名片%s次" +
                        "<br/>2. 客户%s位；浏览%s次；微聊%s次；预约%s个";

        //群发消息体
        List<CreateMessageDTO> createMessageDTOList = new ArrayList<>();

        for (EmployeeDailyDto employeeDailyDto : employeeDailyDtoList) {
            CreateMessageDTO createMessageDTO = new CreateMessageDTO();

            createMessageDTO.setRemindModeEnum(RemindModeEnum.SIDE_MESSAGE);
            createMessageDTO.setMessageTypeEnum(MessageTypeEnum.BUSINESS_MESSAGE);
            createMessageDTO.setSender(MSG_TRIGGER_SYS);

            ReceiverDTO receiverDTO = new ReceiverDTO();
            receiverDTO.setReceiverType(ReceiverTypeEnum.EMPLOYEE);
            receiverDTO.setReceiverUuids(Lists.newArrayList(employeeDailyDto.getEmployeeUniqueUuid()));

            createMessageDTO.setReceiverDTOList(Lists.newArrayList(receiverDTO));
            createMessageDTO.setTitle(date + "数据个人日报");
            createMessageDTO.setContent( String.format(PROCESS_CHANGE_MORTGAGE, employeeDailyDto.getShares().toString(),
                    employeeDailyDto.getClients().toString(), employeeDailyDto.getBrowses().toString(),
                    employeeDailyDto.getChats().toString(), employeeDailyDto.getReservations().toString()));
            createMessageDTO.setRemind(true);
            createMessageDTO.setSubMessageType("WECHATAPP");
            createMessageDTO.setSubTitle(MESSAGE_SUB_TITLE);
            createMessageDTO.setBusinessUuid(employeeDailyDto.getEmployeeUniqueUuid());
            createMessageDTOList.add(createMessageDTO);
        }

        CreateMessageListRequest createMessageListRequest = new CreateMessageListRequest();
        createMessageListRequest.setCreateMessageDTOList(createMessageDTOList);
        try {
            JSONObject jsonObject = gatewayTemplate.postForObject(V20_SENT_ALL_MESSAGE_API, createMessageListRequest, headers, JSONObject.class);
        } catch (Exception e) {
            log.error("sent V20 EmployeeDaily Message error:", e);
        }
        log.info("群发经纪人行为日报成功~");
    }



    private HttpHeaders getHeaders(SyncCommon syncCommon) {
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        headers.add("X-AUTH-APP-ID", syncCommon.getAppId());
        headers.add("X-AUTH-KEY", syncCommon.getAppKey());
        headers.add("companyUuid", syncCommon.getCompanyUuid());
        log.info("========>headers:{}", JSON.toJSONString(headers));
        return headers;
    }

    private void httpRequestData(SyncCommon syncCommon, String apiUrl, List<EmployeeDailyDto> dailyDtoList) {
        HttpHeaders headers = getHeaders(syncCommon);
        DataRequest dataRequest = new DataRequest();
        dataRequest.setParam(dailyDtoList);
        String url = syncCommon.getDomain() + apiUrl;
        String result = null;
        log.info("sync params {},header {}", dataRequest, headers);
        try {
            result = template.postForObject(url, new HttpEntity<>(dailyDtoList, headers), String.class);
            log.info("sync result {}", result);
        } catch (Exception e) {
            log.error("httpRequest error", e);
        }
    }

}
